import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 
 * @author Pietro Bua & Rohmin Mirza
 *
 */
public class ReplacementSelection
{
	private RSHeap heap;
	private int[] input;
	private RandomFileGenerator randomGen;
	private int heapSize = 4;
	private int inputFileIndex = 0;
	private BufferedWriter bw;
	private ArrayList<String> runFileNames;
	
	/**
	 * 
	 */
	public ReplacementSelection()
	{
		randomGen = new RandomFileGenerator();
		runFileNames = new ArrayList<String>();
	}

	/**
	 * 
	 * @param newHeapSize
	 */
	public void setHeapSize(int newHeapSize)
	{
		heapSize = newHeapSize;
	}
	
	/**
	 * 
	 * @return
	 */
	public ArrayList<String> getRunFileNames()
	{
		return runFileNames;
	}
	
	/**
	 * 
	 * @return
	 */
	public RSHeap buildHeap()
	{
		RSHeap oldHeap = heap;
		RSHeap newHeap = new RSHeap(heapSize);
		
		int elementsInserted =0;
		// check if it's the first heap 
		if (oldHeap != null)
		{
			// if it has a deadspace
			if (oldHeap.size() != oldHeap.getHeapArray().length)
			{
				for (int i=oldHeap.size()+1; i<oldHeap.getHeapArray().length-1; i++)
				{
					newHeap.insert(oldHeap.getHeapArray()[i]);
					elementsInserted++;
				}
			}
		}
		
		for (int i = elementsInserted; i < heapSize-1; i++)
		{
			newHeap.insert(getNext());
			elementsInserted++;
		}
		
		return newHeap;
	}
	
	/**
	 * 
	 * @param amountOfElements
	 */
	public void createInputFile(int amountOfElements){
		input = randomGen.generateInputArray(amountOfElements);
	}
	
	/**
	 * 
	 */
	public void createRuns()
	{
		int runNr = 0;
		// While there are elements to be read
		while (!fileIsEmpty()){
			heap = buildHeap();
			runNr++;
			String fileName = "run " + runNr +".txt";
			bw = initWriter(fileName);
			
			// while there are elements to be read 
			// and there are still elements in the heap (excluding deadspace)
			while( (heap.size()>-1)&&(! fileIsEmpty()) )
			{
				int next = getNext();
				
				//write root node to the output file 
				writeToFile(bw, heap.getSmallest());
				
				// if the next element is bigger then the root
				// put it as root
				if( next >=heap.getSmallest() )
				{
					heap.setMin(next);
				} 
				else 
				{
					// if the next element is smaller then the root
					// put the last element into the root

					heap.setElement(0, heap.getElement(heap.size()));
					
					// put the next element into the old slot of the last element
					heap.setElement(heap.size(), next);
					
					// mark the last element as deadspace
					heap.moveLastToDeadspace();
				}
				// rearrange the heap into a minheap
				heap.percoladeUp(0);
			}
		}
	}

	/**
	 * 
	 * @return
	 */
	public int getNext(){
		int tmpInt = input[inputFileIndex];
		inputFileIndex++;
		return tmpInt;
	}

	/**
	 * 
	 * @param fileName
	 * @return
	 */
	public BufferedWriter initWriter(String fileName)
	{
		try 
		{
			bw = new BufferedWriter(new FileWriter(new File(fileName)));
			runFileNames.add(fileName);
		//	System.out.println("new run started, now writing to: " + fileName);
			return bw;
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 
	 * @param bw
	 * @param element
	 */
	public void writeToFile(BufferedWriter bw, int element)
	{
		try 
		{
			bw.write(Integer.toString(element));
			bw.newLine();
			bw.flush();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @return
	 */
	public boolean fileIsEmpty()
	{
		if (input.length == inputFileIndex+1)
		{
			return true;
		} 
		else 
		{
			return false;
		}
	}
	
}
